package com.example.smartgreenhouse.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.smartgreenhouse.WebSocketServer.ThresholdWebSocketServer;
import com.example.smartgreenhouse.entity.ThresholdHistory;
import com.example.smartgreenhouse.entity.ThresholdSettings;
import com.example.smartgreenhouse.exception.BusinessException;
import com.example.smartgreenhouse.mapper.ThresholdHistoryMapper;
import com.example.smartgreenhouse.mapper.ThresholdSettingsMapper;
import com.example.smartgreenhouse.mqtt.MqttMessageSender;
import com.example.smartgreenhouse.service.ThresholdService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

@Slf4j
@Service
public class ThresholdServiceImpl implements ThresholdService {

    private final ThresholdSettingsMapper thresholdSettingsMapper;
    private final ThresholdHistoryMapper historyMapper;


    @Value("${mqtt.topic.threshold.soil_moisture}")
    private String topicSoilMoisture;

    @Value("${mqtt.topic.threshold.air_temperature}")
    private String topicAirTemperature;

    @Value("${mqtt.topic.threshold.air_humidity}")
    private String topicAirHumidity;

    @Value("${mqtt.topic.threshold.light_intensity}")
    private String topicLightIntensity;

    @Autowired
    private MqttMessageSender mqttMessageSender;
    private final ThresholdWebSocketServer thresholdWebSocketServer;

    public ThresholdServiceImpl(ThresholdSettingsMapper settingsMapper,
                                ThresholdHistoryMapper historyMapper, ThresholdWebSocketServer thresholdWebSocketServer) {
        this.thresholdSettingsMapper = settingsMapper;
        this.historyMapper = historyMapper;
        this.thresholdWebSocketServer = thresholdWebSocketServer;
    }

    @Override
    public ThresholdSettings setThreshold(String type, int minValue, int maxValue, String operator) {

        validateThreshold(type, minValue, maxValue);


        ThresholdSettings settings = new ThresholdSettings();
        settings.setType(type);
        settings.setMinValue(minValue);
        settings.setMaxValue(maxValue);


        // 更新或插入逻辑
        ThresholdSettings existing = thresholdSettingsMapper.selectOne(
                new QueryWrapper<ThresholdSettings>().eq("type", type));

        if (existing != null) {
            settings.setId(existing.getId());
            thresholdSettingsMapper.updateById(settings);

            // 保存历史记录
            ThresholdHistory history = new ThresholdHistory();
            history.setSettingId(existing.getId());
            history.setType(existing.getType());
            history.setMinValue(existing.getMinValue());
            history.setMaxValue(existing.getMaxValue());
            history.setOperator(operator);
            historyMapper.insert(history);

        } else {
            thresholdSettingsMapper.insert(settings);
        }

        // 新增：发送阈值到硬件
        sendThresholdToHardware(type, minValue, maxValue);

        // 新增WebSocket推送
        thresholdWebSocketServer.sendThresholdUpdate(type, minValue, maxValue);

        return settings;
    }


    private void sendThresholdToHardware(String type, int minValue, int maxValue) {
        try {
            String topic = getTopicByType(type);
            String payload = String.format("{\"minValue\":%d,\"maxValue\":%d}", minValue, maxValue);

            mqttMessageSender.publish(topic, payload);
            log.info("已发送阈值设置到mqtt:  min={}, max={}",  minValue, maxValue);
        } catch (Exception e) {
            log.error("MQTT发布失败 | 类型: {} | 错误: {}", type, e.getMessage());
            throw new RuntimeException("阈值设置发送失败，请检查MQTT连接配置", e);
        }
    }

    private void validateThreshold(String type, int min, int max) {
        if (min > max) {
            throw new BusinessException("minValue不能大于maxValue");
        }

        switch (type) {
            case "soil_moisture":
                if (min < 10 || max > 90) throw new BusinessException("土壤湿度范围应为10%-90%");
                break;
            case "air_temperature":
                if (min < -10 || max > 50) throw new BusinessException("空气温度范围应为-10°C-50°C");
                break;
            case "air_humidity":
                if (min < 10 || max > 100) throw new BusinessException("空气湿度范围应为10%-100%");
                break;
            case "light_intensity":
                if (min < 100 || max > 2000) throw new BusinessException("光照强度范围应为100-2000lux");
                break;
            default:
                throw new BusinessException("无效的阈值类型");
        }
    }


    @Override
    public List<ThresholdHistory> getHistoryByType(String type) {
        // 参数校验（可选）
        if (!Arrays.asList("soil_moisture", "air_temperature", "air_humidity", "light_intensity").contains(type)) {
            throw new BusinessException("无效的阈值类型");
        }

        // 查询历史记录并按时间倒序排列
        return historyMapper.selectHistoryByType(type);
    }


    @Override
    public ThresholdSettings getCurrentThreshold(String type) {
        // 参数校验（可选）
        if (!Arrays.asList("soil_moisture", "air_temperature", "air_humidity", "light_intensity").contains(type)) {
            throw new BusinessException("无效的阈值类型");
        }

        // 构建查询条件
        QueryWrapper<ThresholdSettings> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", type);

        // 查询当前有效阈值
        ThresholdSettings currentSettings = thresholdSettingsMapper.selectOne(queryWrapper);

        // 处理未找到情况
        if (currentSettings == null) {
            throw new BusinessException("当前没有生效的" + getTypeName(type) + "阈值设置");
        }

        return currentSettings;
    }

    // 辅助方法：获取类型中文名
    private String getTypeName(String type) {
        switch (type) {
            case "soil_moisture": return "土壤湿度";
            case "air_temperature": return "空气温度";
            case "air_humidity": return "空气湿度";
            case "light_intensity": return "光照强度";
            default: return "";
        }
    }

    private String getTopicByType(String type) {
        switch (type) {
            case "soil_moisture": return topicSoilMoisture;
            case "air_temperature": return topicAirTemperature;
            case "air_humidity": return topicAirHumidity;
            case "light_intensity": return topicLightIntensity;
            default: throw new BusinessException("无效的阈值类型");
        }
    }
}